//
// Created by hsj on 2024-1-5.
// 编译：gcc file_serve_win.c -LH:\mingw\mingw64\x86_64-w64-mingw32\lib -lws2_32 -o file_serve_win
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>

#ifdef WIN32
//windows minGW64
//inet_ntop函数：_WIN32_WINNT
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#include <winsock2.h>
#include <ws2tcpip.h>
//#pragma comment(lib,"ws2_32.lib")
#else
//linux  gcc
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#define BUF_SIZE 30
void ErrorHandling(char *message);
int main(int argc, char *argv[]){
    WSADATA wsaData;
    SOCKET hServSock, hClntSock;
    FILE *fp;
    char buf[BUF_SIZE];
    int readCnt ;
    SOCKADDR_IN servAdr, clntAdr ;
    int clntAdrSz ;
    char port[] = "8889";

    if(WSAStartup (MAKEWORD(2, 2),&wsaData)!=0)
        ErrorHandling( "WSAStartup() error!");

    fp=fopen("file_serve_win.c", "rb");
    hServSock=socket(PF_INET, SOCK_STREAM, 0);

    memset(&servAdr, 0,sizeof(servAdr));
    servAdr.sin_family=AF_INET;
    servAdr.sin_addr.s_addr=htonl(INADDR_ANY);
    servAdr.sin_port=htons(atoi(/*argv[1]*/port));

    bind(hServSock, (SOCKADDR* )&servAdr, sizeof(servAdr));

    listen(hServSock, 128);

    clntAdrSz=sizeof(clntAdr);
    hClntSock=accept(hServSock, (SOCKADDR* )&clntAdr, &clntAdrSz);
    while(1){
        readCnt=fread( (void*)buf, 1, BUF_SIZE, fp);
        if(readCnt<BUF_SIZE)
        {
            send(hClntSock, (char* )&buf, readCnt, 0);
            break;
        }
        send(hClntSock, (char*)&buf, BUF_SIZE, 0);
    }
    /**
     *
        howto 在 Linux 下有以下取值：
            SHUT_RD：断开输入流。套接字无法接收数据（即使输入缓冲区收到数据也被抹去），无法调用输入相关函数。
            SHUT_WR：断开输出流。套接字无法发送数据，但如果输出缓冲区中还有未传输的数据，则将传递到目标主机。
            SHUT_RDWR：同时断开 I/O 流。相当于分两次调用 shutdown()，其中一次以 SHUT_RD 为参数，另一次以 SHUT_WR 为参数。

        howto 在 Windows 下有以下取值：
            SD_RECEIVE：关闭接收操作，也就是断开输入流。
            SD_SEND：关闭发送操作，也就是断开输出流。
            SD_BOTH：同时关闭接收和发送操作。
     */
    shutdown(hClntSock,SD_SEND);

    recv(hClntSock, (char*)buf, BUF_SIZE, 0);
    printf("Message from client --win: %s \n", buf);

    fclose(fp);
    closesocket(hClntSock);
    closesocket(hServSock);
    WSACleanup();

    return EXIT_SUCCESS;
}
void ErrorHandling( char *message){
    fputs (message, stderr);
    fputc('\n', stderr);
    exit(1);
}